package com.wmd.core.util;

import com.wmd.core.function.SFunction;

import java.lang.invoke.SerializedLambda;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Simple to Introduction
 *
 * @projectName:scs-platform
 * @packageName:com.wmd.scs.util
 * @className:SerializedLambdaUtil
 * @Description:[一句话描述该类的功能]
 * @Author:luyincheng
 * @CreateDate:2021/1/20 16:35
 * @blog:[方法具体上行/下行参数文档]
 */
public class SerializedLambdaUtil {

    public static<T> SerializedLambda getSerializedLambda(SFunction<T, ?> func) {
        Class clazz = func.getClass();
        return Optional.ofNullable(FUNC_CACHE.get(clazz))
                .map(WeakReference::get)
                .orElseGet(() -> {
                    try {
                        // 通过获取对象方法，判断是否存在该方法
                        Method method = func.getClass().getDeclaredMethod("writeReplace");
                        method.setAccessible(Boolean.TRUE);
                        // 利用jdk的SerializedLambda 解析方法引用
                        SerializedLambda serializedLambda = (SerializedLambda) method.invoke(func);
                        FUNC_CACHE.put(clazz, new WeakReference<>(serializedLambda));
                        return serializedLambda;
                    } catch (ReflectiveOperationException e) {
                        throw new RuntimeException(e);
                    }
                });
    }

    private static final Map<Class, WeakReference<SerializedLambda>> FUNC_CACHE = new ConcurrentHashMap<>();


    public static String resolveFieldName(String getMethodName) {
        if (getMethodName.startsWith("get")) {
            getMethodName = getMethodName.substring(3);
        } else if (getMethodName.startsWith("is")) {
            getMethodName = getMethodName.substring(2);
        }
        // 小写第一个字母
        return firstToLowerCase(getMethodName);
    }

    private static String firstToLowerCase(String param) {
        if (StringUtil.isEmpty(param)) {
            return "";
        }
        return param.substring(0, 1).toLowerCase() + param.substring(1);
    }
}
